package com.cctc.rds.scheduler.server.storage.impl;

import com.cctc.rds.nrpc.core.util.JsonUtils;
import com.cctc.rds.scheduler.core.task.TaskLog;
import com.cctc.rds.scheduler.core.task.TaskStatus;
import com.cctc.rds.scheduler.server.storage.Storage;
import com.cctc.rds.scheduler.server.storage.leveldb.LevelDB;
import org.iq80.leveldb.DB;
import org.iq80.leveldb.DBException;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * 本机任务日志操作 [接口] 实现类。
 */
public class LevelDBStorage implements Storage {
    private DB database;

    public LevelDBStorage() {
        DB database = LevelDB.get();
        if (database == null) throw new DBException("LevelDB 数据库未打开！！！");
        this.database = database;
    }

    @Override
    public void save(String app, long taskId, TaskLog taskLog) {
        byte[] key = getKey(app, taskId, taskLog.getStatus());
        database.put(key, JsonUtils.toJson(taskLog).getBytes(StandardCharsets.UTF_8));
        this.remove(app, taskId, taskLog.getStatus());
    }

    @Override
    public TaskLog get(String app, long taskId) {
        byte[] value = null;
        for (TaskStatus status : TaskStatus.values()) {
            byte[] key = getKey(app, taskId, status.getStatus());
            value = database.get(key);
            if (value != null) break;
        }
        return value == null ? null : JsonUtils.fromJson(new String(value, StandardCharsets.UTF_8), TaskLog.class);
    }

    @Override
    public void remove(String app, long taskId) {
        this.remove(app, taskId, null);
    }

    private void remove(String app, long taskId, String excludeStatus) {
        for (TaskStatus status : TaskStatus.values()) {
            if (excludeStatus != null && excludeStatus.equals(status.getStatus())) continue;
            byte[] key = getKey(app, taskId, status.getStatus());
            database.delete(key);
        }
    }

    private byte[] getKey(String app, long taskId, String status) {
        return (app + "::" + taskId + "::" + status).getBytes(StandardCharsets.UTF_8);
    }

    @Override
    public void close() throws IOException {
        if (database != null) LevelDB.close();
    }
}
